package com.kalvan.web.utils;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import sun.net.util.IPAddressUtil;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.util.Map.Entry;

/**
 * 把数组类型的参数值转换为字符串参数值
 *
 * @author chenliang
 * @version 2017年9月28日
 * @see RequestUtils
 */
public class RequestUtils {
    /**
     * 获取请求方ip
     * @return ip
     */
    public static String getIpAddr(){
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getRequest();
        return getIpAddr(request);
    }

    /**
     * 获取请求方ip
     * @param request
     * @return ip
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if (ip.equals("127.0.0.1") || ip.equals("0:0:0:0:0:0:0:1")) {
                // 根据网卡取本机配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    // e.printStackTrace();
                }
                ip = inet.getHostAddress();
            }
        }
        /**
         * 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割 "***.***.***.***".length()= 15
         * 如 145.241.192.99, 140.207.83.127 前面的是代理 ip，后面的是真实ip
         */
        if (ip != null && ip.length() > 15) {
            if (ip.lastIndexOf(",") > 0) {
                ip = ip.substring(ip.lastIndexOf(",") + 1);

            }
        }
        if (ip != null && ip.length() > 0) {
            ip = ip.trim();
        }
        return ip;
    }

    /**
     * 获取请求参数
     *
     * @param request
     * @return
     */
    public static Map<String, String> convertRequestMapToStringMap(
            HttpServletRequest request) {
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();

        for (Entry<String, String[]> entry : requestParams.entrySet()) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            String valueStr = "";

            if (values != null) {
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i]
                            : valueStr + values[i] + ",";
                }

                params.put(name, valueStr);
            }

        }

        return params;
    }

    /**
     * 把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串<br>
     *
     * @param params 需要排序并参与字符拼接的参数组
     * @return 拼接后字符串
     */
    public static String createLinkStringByGet(Map<String, String> params) throws Exception {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        String prestr = "";
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            // encode URLEncoder.encode(value, "UTF-8")
            if (i == keys.size() - 1) {
                // 拼接时，不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }
        return prestr;
    }

    public static boolean internalIp(String ip) {
        byte[] addr = IPAddressUtil.textToNumericFormatV4(ip);
        return internalIp(addr);
    }

    static boolean internalIp(byte[] addr) {
        final byte b0 = addr[0];
        final byte b1 = addr[1];
        //10.x.x.x/8
        final byte SECTION_1 = 0x0A;
        //172.16.x.x/12
        final byte SECTION_2 = (byte) 0xAC;
        final byte SECTION_3 = (byte) 0x10;
        final byte SECTION_4 = (byte) 0x1F;
        //192.168.x.x/16
        final byte SECTION_5 = (byte) 0xC0;
        final byte SECTION_6 = (byte) 0xA8;
        switch (b0) {
            case SECTION_1:
                return true;
            case SECTION_2:
                if (b1 >= SECTION_3 && b1 <= SECTION_4) {
                    return true;
                }
            case SECTION_5:
                switch (b1) {
                    case SECTION_6:
                        return true;
                }
            default:
                return false;
        }
    }

    /**
     * 获取域名
     *
     * @param httpRequest
     * @return
     */
    public static String getDomain(HttpServletRequest httpRequest) {
        String schemeXforward = httpRequest.getHeader("X-Forwarded-Proto");
        String scheme = httpRequest.getScheme();
        String serverName = httpRequest.getServerName();
        String serverPort = httpRequest.getServerPort() + "";
        String contextPath = httpRequest.getContextPath();
        String domain;
        if ("80".equals(serverPort)) {
            serverPort = "";
        } else {
            serverPort = ":" + serverPort;
        }
        if (schemeXforward == null) {
            domain = scheme + "://" + serverName + serverPort;
        } else {
            domain = schemeXforward + "://" + serverName + serverPort;
        }
        //  String basepath = domain + contextPath;
        return domain;
    }
}
